﻿using Common.Share;
using log4net;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace VirtualWall
{
    public class LEDHandle
    {
        private static readonly ILog log = LogManager.GetLogger("LED");

        public static void SendMsgToCameraLED(int handle, string line1, string line2, string line3, string line4, string tts, string rgb)
        {
            var selectedController = ConfigurationManager.AppSettings["SelectedController"];
            switch (selectedController)
            {
                case "道通物联":
                    Dtwl_Led(handle, line1, line2, line3, line4, tts, rgb);
                    break;
                case "方控":
                    Fk_Led(handle, 1, line1, tts, rgb);
                    Fk_Led(handle, 2, line2, tts, rgb);
                    Fk_Led(handle, 3, line3, tts, rgb);
                    Fk_Led(handle, 4, line4, tts, rgb);
                    break;
                default:
                    Dtwl_Led(handle, line1, line2, line3, line4, tts, rgb);
                    break;
            }
        }

        /// <summary>
        /// 方控LED发送
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="line3"></param>
        /// <param name="line4"></param>
        /// <param name="tts"></param>
        /// <param name="rgb"></param>
        private static void Fk_Led(int handle, int rowIndex, string line, string tts, string rgb)
        {
            //因为屏幕不支持 切换颜色，所以统一为黄色。
            byte[] FK_Head = { (byte)rowIndex, 0x3C, 0x03, 0x00 };//显示格式
            byte[] FK_Body = System.Text.Encoding.Default.GetBytes(line);//屏显内容
            byte[] Data = FK_Head.Concat(FK_Body).ToArray();//拼接两数组

            int len = Data.Length + 11;//总长度
            byte[] sendData = new byte[len];
            sendData[0] = 0xAA;//包头，2字节
            sendData[1] = 0x55;
            sendData[2] = 0x1E;//流水号
            sendData[3] = 0x64;//地址
            sendData[4] = 0x00;//业务类型
            sendData[5] = 0x27;//命令
            sendData[6] = (byte)(Data.Length >> 8);//长度高位
            sendData[7] = (byte)Data.Length;//长度低位
            int i = 8;
            for (; i < 8 + Data.Length; i++)
            {
                sendData[i] = Data[i - 8];
            }
            //CRC16校验
            byte[] crcByte = CRC.Run(sendData, 2, len - 1);
            sendData[i++] = crcByte[0];
            sendData[i++] = crcByte[1];
            sendData[i++] = 0xAF;//结尾

            GCHandle hObject = GCHandle.Alloc(sendData, GCHandleType.Pinned);
            IntPtr pObject = hObject.AddrOfPinnedObject();
            //var tt = Int32ToHex(sendData);
            VzClientSDK.VzLPRClient_SerialSend(handle, pObject, sendData.Length);

            if (hObject.IsAllocated)
                hObject.Free();

            Thread.Sleep(70);
        }

        public static string Int32ToHex(byte[] data, string split = " ")
        {
            if (data == null) return null;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                if (split == "" || split == null)
                {
                    sb.AppendFormat("{0:x2}", data[i]);
                }
                else
                {
                    sb.AppendFormat("{0:x2}" + split, data[i]);
                }
            }
            string result = sb.ToString().Trim().ToUpper();
            if (result.EndsWith(split))
            {
                int index = result.LastIndexOf(split);
                result = result.Remove(index, split.Length);
            }
            return result;
        }

        /// <summary>
        /// 将16进制的字符串转为byte[]
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] StrToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// 道通物联LED发送
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="line3"></param>
        /// <param name="line4"></param>
        /// <param name="tts"></param>
        /// <param name="rgb"></param>
        private static void Dtwl_Led(int handle, string line1, string line2, string line3, string line4, string tts, string rgb)
        {
            //去空格
            line1 = line1.Replace(" ", string.Empty).Replace("\0", string.Empty).Trim();
            line2 = line2.Replace(" ", string.Empty).Replace("\0", string.Empty).Trim();
            line3 = line3.Replace(" ", string.Empty).Replace("\0", string.Empty).Trim();
            line4 = line4.Replace(" ", string.Empty).Replace("\0", string.Empty).Trim();

            //为空处理
            line1 = string.IsNullOrWhiteSpace(line1) ? " " : line1;
            line1 = string.IsNullOrWhiteSpace(line1) ? " " : line1;
            line1 = string.IsNullOrWhiteSpace(line1) ? " " : line1;
            line1 = string.IsNullOrWhiteSpace(line1) ? " " : line1;

            line1 = Str2Hex(line1);
            line2 = Str2Hex(line2);
            line3 = Str2Hex(line3);
            line4 = Str2Hex(line4);
            tts = Str2Hex(tts);
            string line1Len = Convert.ToString(line1.Length / 3, 16).ToUpper().PadLeft(2, '0');
            string line2Len = Convert.ToString(line2.Length / 3, 16).ToUpper().PadLeft(2, '0');
            string line3Len = Convert.ToString(line3.Length / 3, 16).ToUpper().PadLeft(2, '0');
            string line4Len = Convert.ToString(line4.Length / 3, 16).ToUpper().PadLeft(2, '0');
            string ttsLen = Convert.ToString(tts.Length / 3, 16).ToUpper().PadLeft(2, '0');

            string strHead = "00 64 FF FF 6E DL 00 04 ";
            string strLine1 = "00 01 01 05 00 R G 00 00 DL DATA";
            string strLine2 = "01 01 01 05 00 R G 00 00 DL DATA";
            string strLine3 = "02 01 01 05 00 R G 00 00 DL DATA";
            string strLine4 = "03 01 01 05 00 R G 00 00 DL DATA";
            string strTTS = "0A VTL DATA";

            if (rgb == "r")
            {
                strLine1 = strLine1.Replace("R", "FF").Replace("G", "00");
                strLine2 = strLine2.Replace("R", "FF").Replace("G", "00");
                strLine3 = strLine3.Replace("R", "FF").Replace("G", "00");
                strLine4 = strLine4.Replace("R", "FF").Replace("G", "00");
            }
            else if (rgb == "g")
            {
                strLine1 = strLine1.Replace("R", "00").Replace("G", "FF");
                strLine2 = strLine2.Replace("R", "00").Replace("G", "FF");
                strLine3 = strLine3.Replace("R", "00").Replace("G", "FF");
                strLine4 = strLine4.Replace("R", "00").Replace("G", "FF");
            }
            strLine1 = strLine1.Replace("DL", line1Len).Replace("DATA", line1);
            strLine2 = strLine2.Replace("DL", line2Len).Replace("DATA", line2);
            strLine3 = strLine3.Replace("DL", line3Len).Replace("DATA", line3);
            strLine4 = strLine4.Replace("DL", line4Len).Replace("DATA", line4);
            strTTS = strTTS.Replace("VTL", ttsLen).Replace("DATA", tts);

            string data = strLine1 + "0D " + strLine2 + "0D " + strLine3 + "0D " + strLine4 + "00 " + strTTS + "00 ";
            string dataLen = Convert.ToString(data.Length / 3 + 2, 16).ToUpper().PadLeft(2, '0');

            strHead = strHead.Replace("DL", dataLen);
            data = strHead + data;
            string strcrc = CRC.ToModbusCRC16(data, true);
            strcrc = strcrc.Insert(2, " ");
            data = data + strcrc;

            byte[] send_buf = new byte[1024];
            string new_content = data.Insert(data.Length, " ");
            int txt_len = new_content.Length;
            char[] txt_buf = new_content.ToCharArray();

            int index = 0;

            char[] strHex = new char[3];
            byte uc;
            for (int i = 0; i < txt_len - 2; i += 3)
            {
                if (txt_buf[i + 2] != ' ')
                {
                    //MessageBox.Show("16 进制数据输入格式不正确");
                    log.Info($" 16 进制数据输入格式不正确_1 txt_buf:{new string(txt_buf)}");
                    return;
                }

                strHex[0] = txt_buf[i];
                strHex[1] = txt_buf[i + 1];
                strHex[2] = (char)0;

                for (int j = 0; j < 2; j++)
                {
                    if (strHex[j] < '0' || (strHex[j] > '9' && strHex[j] < 'A') || (strHex[j] > 'F' &&
                        strHex[j] < 'a') || strHex[j] > 'f')
                    {
                        //MessageBox.Show("16 进制数据输入格式不正确");
                        log.Info($" 16 进制数据输入格式不正确_2  strHex:{new string(strHex)} ");
                        return;
                    }
                }

                string hex_value = new string(strHex);
                uc = byte.Parse(hex_value, System.Globalization.NumberStyles.HexNumber);
                send_buf[index] = uc;
                index++;
            }

            GCHandle hObject = GCHandle.Alloc(send_buf, GCHandleType.Pinned);
            IntPtr pObject = hObject.AddrOfPinnedObject();

            VzClientSDK.VzLPRClient_SerialSend(handle, pObject, index);

            if (hObject.IsAllocated)
                hObject.Free();
        }

        public static void SwitchLight(int handle, bool isOpen = true)
        {

            var selectedController = ConfigurationManager.AppSettings["SelectedController"];
            switch (selectedController)
            {
                case "道通物联":
                    Dtwl_SwitchLight(handle, isOpen);
                    break;
                case "方控":
                    Fk_SwitchLight(handle, isOpen);
                    break;
                default:
                    Dtwl_SwitchLight(handle, isOpen);
                    break;
            }
        }

        private static void Fk_SwitchLight(int handle, bool isOpen = true)
        {
            //string strHead = "00 64 FF FF 0F DL ";
            string strHead = "00 64 FF FF 0F 06 ";
            var data = "00 01 00 00 00 FF ";
            //data = "00 01 00 00 00 0A ";
            if (!isOpen)
            {
                data = "02 01 00 00 00 02 ";
            }
            string dataLen = Convert.ToString(data.Length / 3 + 2, 16).ToUpper().PadLeft(2, '0');

            // strHead = strHead.Replace("DL", dataLen);
            data = strHead + data;
            string strcrc = CRC.ToModbusCRC16(data, true);
            strcrc = strcrc.Insert(2, " ");
            data = data + strcrc;

            byte[] send_buf = new byte[1024];
            string new_content = data.Insert(data.Length, " ");
            int txt_len = new_content.Length;
            char[] txt_buf = new_content.ToCharArray();

            int index = 0;

            char[] strHex = new char[3];
            byte uc;
            for (int i = 0; i < txt_len - 2; i += 3)
            {
                if (txt_buf[i + 2] != ' ')
                {
                    //MessageBox.Show("16 进制数据输入格式不正确");
                    log.Info($" 16 进制数据输入格式不正确_1 txt_buf:{new string(txt_buf)}");
                    return;
                }

                strHex[0] = txt_buf[i];
                strHex[1] = txt_buf[i + 1];
                strHex[2] = (char)0;

                for (int j = 0; j < 2; j++)
                {
                    if (strHex[j] < '0' || (strHex[j] > '9' && strHex[j] < 'A') || (strHex[j] > 'F' &&
                        strHex[j] < 'a') || strHex[j] > 'f')
                    {
                        //MessageBox.Show("16 进制数据输入格式不正确");
                        log.Info($" 16 进制数据输入格式不正确_2  strHex:{new string(strHex)} ");
                        return;
                    }
                }

                string hex_value = new string(strHex);
                uc = byte.Parse(hex_value, System.Globalization.NumberStyles.HexNumber);
                send_buf[index] = uc;
                index++;
            }

            GCHandle hObject = GCHandle.Alloc(send_buf, GCHandleType.Pinned);
            IntPtr pObject = hObject.AddrOfPinnedObject();

            var f = VzClientSDK.VzLPRClient_SerialSend(handle, pObject, index);

            if (hObject.IsAllocated)
                hObject.Free();
        }

        private static void Dtwl_SwitchLight(int handle, bool isOpen = true)
        {
            //string strHead = "00 64 FF FF 0F DL ";
            string strHead = "00 64 FF FF 0F 06 ";
            var data = "00 01 00 00 00 FF ";
            //data = "00 01 00 00 00 0A ";
            if (!isOpen)
            {
                data = "02 01 00 00 00 02 ";
            }
            string dataLen = Convert.ToString(data.Length / 3 + 2, 16).ToUpper().PadLeft(2, '0');

            // strHead = strHead.Replace("DL", dataLen);
            data = strHead + data;
            string strcrc = CRC.ToModbusCRC16(data, true);
            strcrc = strcrc.Insert(2, " ");
            data = data + strcrc;

            byte[] send_buf = new byte[1024];
            string new_content = data.Insert(data.Length, " ");
            int txt_len = new_content.Length;
            char[] txt_buf = new_content.ToCharArray();

            int index = 0;

            char[] strHex = new char[3];
            byte uc;
            for (int i = 0; i < txt_len - 2; i += 3)
            {
                if (txt_buf[i + 2] != ' ')
                {
                    //MessageBox.Show("16 进制数据输入格式不正确");
                    log.Info($" 16 进制数据输入格式不正确_1 txt_buf:{new string(txt_buf)}");
                    return;
                }

                strHex[0] = txt_buf[i];
                strHex[1] = txt_buf[i + 1];
                strHex[2] = (char)0;

                for (int j = 0; j < 2; j++)
                {
                    if (strHex[j] < '0' || (strHex[j] > '9' && strHex[j] < 'A') || (strHex[j] > 'F' &&
                        strHex[j] < 'a') || strHex[j] > 'f')
                    {
                        //MessageBox.Show("16 进制数据输入格式不正确");
                        log.Info($" 16 进制数据输入格式不正确_2  strHex:{new string(strHex)} ");
                        return;
                    }
                }

                string hex_value = new string(strHex);
                uc = byte.Parse(hex_value, System.Globalization.NumberStyles.HexNumber);
                send_buf[index] = uc;
                index++;
            }

            GCHandle hObject = GCHandle.Alloc(send_buf, GCHandleType.Pinned);
            IntPtr pObject = hObject.AddrOfPinnedObject();

            var f = VzClientSDK.VzLPRClient_SerialSend(handle, pObject, index);

            if (hObject.IsAllocated)
                hObject.Free();
        }

        private static string Str2Hex(string s)
        {
            string result = string.Empty;

            byte[] arrByte = Encoding.GetEncoding("GB2312").GetBytes(s);
            for (int i = 0; i < arrByte.Length; i++)
            {
                result += Convert.ToString(arrByte[i], 16) + " ";        //Convert.ToString(byte, 16)把byte转化成十六进制string 
            }

            return result.ToUpper();
        }

    }
}
